﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using canthovieclam.Core.Utilities;
using phudieuhungthinh.BL.Model;
using phudieuhungthinh.DAL;
using phudieuhungthinh.DAL.Repositories;

namespace phudieuhungthinh.BL
{
    public class ProductImpl
    {
        public List<string> GetHighlightProducts(string folder)
        {
            IEnumerable<string> filenames = from fullFilename in Directory.EnumerateFiles(folder, "*.jpg")
                select Path.GetFileName(fullFilename);

            return filenames.ToList();
        }

        public List<string> GetFileInfos(string folder)
        {
            IEnumerable<string> filenames = from fullFilename in Directory.EnumerateFiles(folder, "*.*")
                orderby new FileInfo(fullFilename).LastWriteTime descending
                select Path.GetFileName(fullFilename);

            return filenames.Take(20).ToList();
        }

        public List<ProductModel> PagingProducts(int categoryId, out int rowCount, int? pageSize = null,
            int? pageNum = null)
        {
            var sortClause = new HashSet<string> { "ID DESC", "Orders DESC" };

            var productRepository = new ProductRepository();
            IQueryable<Product> query =
                from x in
                    productRepository.QueryProduct(
                        y =>
                            y.ProductCategories.Any(z => z.CategoryID == categoryId || z.Category.ParentId == categoryId))
                select x;

            for (int i = sortClause.Count - 1; i >= 0; i--)
                query = query.OrderBy(sortClause.ElementAt(i));

            rowCount = query.Count();
            if (pageSize.HasValue && pageNum.HasValue)
                return
                    query.PageIQuery(pageNum.Value, pageSize.Value).ToList().Select(x => new ProductModel(x)).ToList();
            return query.Select(x => new ProductModel(x)).ToList();
        }

        public List<ProductModel> PagingProducts(string url, out int rowCount, int? pageSize = null, int? pageNum = null)
        {
            var cateRep = new CategoryRepository();
            int id = cateRep.GetSingleCategory(x => x.Url == url).ID;

            return PagingProducts(id, out rowCount, pageSize, pageNum);
        }

        public List<ProductModel> GetProductList()
        {
            var productRepository = new ProductRepository();
            List<ProductModel> listProductModel = (from x in productRepository.QueryProduct()
                orderby x.Name
                select new ProductModel(x)).ToList();
            return listProductModel;
        }

        public List<ProductModel> GetProductExcept(int productId)
        {
            var pRep = new ProductRepository();
            var cRep = new ProductCategoriesRepository();
            List<int> query =
                cRep.QueryProductCategories(m => m.ProductID == productId).Select(x => x.CategoryID).ToList();
            List<ProductModel> listProductModel = (from x in pRep.QueryProduct()
                where x.ID != productId && query.Contains(x.ProductCategories.Max(m => m.CategoryID))
                orderby x.Name
                select x).ToList().Select(x => new ProductModel(x)).ToList();
            return listProductModel;
        }

        public void AddProduct(ProductModel productModel, List<ProductCategoriesModel> productCategoriesModelList)
        {
            if (productModel.ImageUrl.StartsWith("http://"))
            {
                string fileName = Path.GetFileName(productModel.ImageUrl);
                productModel.ImageUrl = fileName;
            }

            productModel.Url = StringUtil.RemoveSign4VietnameseString(productModel.Name.ToLower()).Replace(' ', '-');
            productModel.UniqueID = GuidUtils.NewSeqGuid();

            var producRepository = new ProductRepository();
            Product product = productModel.MapProduct();
            producRepository.AddProduct(product);
            producRepository.Commit();
            var producCategoriesRepository = new ProductCategoriesRepository();
            foreach (ProductCategoriesModel item in productCategoriesModelList)
            {
                item.ProductID = product.ID;
                producCategoriesRepository.AddProductCategories(item.MapProductCategories());
            }
            producCategoriesRepository.Commit();
        }

        public void DeleteProduct(ProductModel productModel)
        {
            //Delete product categories of this product
            var productCategoriesImpl = new ProductCategoriesImpl();
            var productCategoriesRepository = new ProductCategoriesRepository();
            List<ProductCategoriesModel> currentProductCategories =
                productCategoriesImpl.GetProductCategories(productModel.ID);
            IList<ProductCategories> deleteItems = currentProductCategories.Select(current => new ProductCategories
            {
                CategoryID = current.CategoryID, ProductID = current.ProductID, UniqueID = current.UniqueID
            }).ToList();
            productCategoriesRepository.DeleteBatchProductCategories(deleteItems);
            productCategoriesRepository.Commit();

            var producRepository = new ProductRepository();
            productModel.IsActive = false;
            producRepository.UpdateProduct(productModel.MapProduct());
            producRepository.Commit();
        }

        public ProductModel GetProductInfo(int id)
        {
            var producRepository = new ProductRepository();
            Product product = producRepository.GetSingleProduct(x => x.ID == id);
            var productModel = new ProductModel(product);
            return productModel;
        }

        public string GetImage(string url)
        {
            var producRepository = new ProductRepository();
            return producRepository.GetSingleProduct(x => x.Url == url).ImageUrl;
        }

        public ProductModel GetProductInfo(string url)
        {
            var producRepository = new ProductRepository();
            Product product = producRepository.GetSingleProduct(x => x.Url == url);
            var productModel = new ProductModel(product);
            return productModel;
        }

        public void UpdateProduct(ProductModel productModel, List<ProductCategoriesModel> productCategoriesModelList)
        {
            if (productModel.ImageUrl.StartsWith("http://"))
            {
                string fileName = Path.GetFileName(productModel.ImageUrl);
                productModel.ImageUrl = fileName;
            }

            productModel.Url = StringUtil.RemoveSign4VietnameseString(productModel.Name.ToLower()).Replace(' ', '-');
            productModel.UniqueID = GuidUtils.NewSeqGuid();

            //Update this product
            var producRepository = new ProductRepository();
            Product product = productModel.MapProduct();
            producRepository.UpdateProduct(product);
            producRepository.Commit();

            //Delete product categories of this product
            var productCategoriesImpl = new ProductCategoriesImpl();
            var productCategoriesRepository = new ProductCategoriesRepository();
            List<ProductCategoriesModel> currentProductCategories =
                productCategoriesImpl.GetProductCategories(productModel.ID);
            IList<ProductCategories> deleteItems = currentProductCategories.Select(current => new ProductCategories
            {
                CategoryID = current.CategoryID, ProductID = current.ProductID, UniqueID = current.UniqueID
            }).ToList();
            productCategoriesRepository.DeleteBatchProductCategories(deleteItems);
            productCategoriesRepository.Commit();

            //Re add product categories of this product
            foreach (ProductCategoriesModel item in productCategoriesModelList)
            {
                item.ProductID = product.ID;
                productCategoriesRepository.AddProductCategories(item.MapProductCategories());
            }
            productCategoriesRepository.Commit();
        }
    }
}